PriorityBlockingQueue
1. 前言
线程安全的无界优先级队列
基于数组实现的二叉堆,原理和结构根PriorityQueue基本一致
2. 源码分析
2.1 数据结构
1 | public class PriorityBlockingQueue<E> extends AbstractQueue<E> |
UML类图如下:
2.2 核心函数
- 构造函数
1 | /** |
- 添加元素: offer(E e)
1 | public boolean offer(E e) { |
流程如下:
- 加锁,检查是否需要扩容,扩容先释放主锁,使用cas自旋锁,容量最少翻倍,释放自旋锁;可能存在竞争,检查是否扩容,如果扩容则复制数组,再度加主锁;
- 看构造入参是否有comparator,没有就使用自然排序;从数组待插入位置和父节点进行比较,如果大于父节点,那就直接待插入位置插入,否则就跟父节点交换,然后循环向上查找;队列数量加1,唤醒非空条件队列上的线程,最后释放锁。
- 取出元素: take()
1 | public E take() throws InterruptedException { |
流程如下:
- 加锁,获取queue[0],清掉堆的最后一个叶子节点,并将其作为比较节点
- 调用从顶向下调整的方法:待调整位置节点左右子节点和之前的叶子节点比较,如果之前叶子节点最小,那就直接放入待调整位置;如果是子节点小,那就取小的那个放入待调整位置,并从子节点位置重新循环查找,循环次数根据2分查找,基本是元素数量的一半就到找到位置
- 删除元素:remove(Object o)
1 | public boolean remove(Object o) { |